using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(C_AnimEvent))]
public class C_AnimEventDrawer : PropertyDrawer
{
    public C_AnimationController controller;

    public SerializedProperty animEventName;
    public SerializedProperty type;

    public SerializedProperty hasSwitchAnim;
    public SerializedProperty switchAnimIndex;
    public SerializedProperty switchAnim;
    public SerializedProperty isSwitchDelay;
    public SerializedProperty switchDelayTime;

    public SerializedProperty hasFunc;
    public SerializedProperty animFuncList;
    public SerializedProperty isFuncDelay;
    public SerializedProperty funcDelayTime;

    public SerializedProperty isSecond;
    public SerializedProperty interruptTime;
    public SerializedProperty isFrameRange;
    public SerializedProperty frameNumber;
    public SerializedProperty isAllFrameRange;
    public SerializedProperty frameRange;

    public SerializedProperty foldout;

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        using (new EditorGUI.PropertyScope(position, label, property))
        {
            controller = property.serializedObject.targetObject as C_AnimationController;

            animEventName = property.FindPropertyRelative("animEventName");
            type = property.FindPropertyRelative("type");

            hasSwitchAnim = property.FindPropertyRelative("hasSwitchAnim");
            switchAnimIndex = property.FindPropertyRelative("switchAnimIndex");
            switchAnim = property.FindPropertyRelative("switchAnim");
            isSwitchDelay = property.FindPropertyRelative("isSwitchDelay");
            switchDelayTime = property.FindPropertyRelative("switchDelayTime");

            hasFunc = property.FindPropertyRelative("hasFunc");
            animFuncList = property.FindPropertyRelative("animFuncList");
            isFuncDelay = property.FindPropertyRelative("isFuncDelay");
            funcDelayTime = property.FindPropertyRelative("funcDelayTime");

            isFrameRange = property.FindPropertyRelative("isFrameRange");
            isAllFrameRange = property.FindPropertyRelative("isAllFrameRange");
            frameNumber = property.FindPropertyRelative("frameNumber");
            frameRange = property.FindPropertyRelative("frameRange");

            foldout = property.FindPropertyRelative("foldout");
            isSecond = property.FindPropertyRelative("isSecond");
            interruptTime = property.FindPropertyRelative("interruptTime");

            EditorGUIUtility.labelWidth = 120;
            position.height = EditorGUIUtility.singleLineHeight;

            var foldoutRect = new Rect(position)
            {
                width = position.width,
                height = position.height,
            };
            var animEventNameRect = new Rect(foldoutRect)
            {
                y = foldoutRect.y + EditorGUIUtility.singleLineHeight + 5,
            };
            var typeRect = new Rect(animEventNameRect)
            {
                y = animEventNameRect.y + EditorGUIUtility.singleLineHeight + 5,
            };

            var hasSwitchAnimRect = new Rect(typeRect)
            {
                y = typeRect.y + EditorGUIUtility.singleLineHeight + 5,
                width = position.width / 3,
            };
            var switchAnimRect = new Rect(typeRect)
            {
                x = hasSwitchAnimRect.xMax,
                y = typeRect.y + EditorGUIUtility.singleLineHeight + 5,
                width = position.width / 1.5f,
            };
            var isSwitchDelayRect = new Rect(hasSwitchAnimRect)
            {
                y = hasSwitchAnimRect.y + EditorGUIUtility.singleLineHeight + 5,
                width = hasSwitchAnimRect.width,
            };
            var switchDelayTimeRect = new Rect(hasSwitchAnimRect)
            {
                x = hasSwitchAnimRect.x + hasSwitchAnimRect.width,
                y = hasSwitchAnimRect.y + EditorGUIUtility.singleLineHeight + 5,
                width = switchAnimRect.width,
            };

            var hasFuncRect = new Rect(hasSwitchAnim.boolValue ? isSwitchDelayRect : hasSwitchAnimRect)
            {
                y = (hasSwitchAnim.boolValue ? isSwitchDelayRect : hasSwitchAnimRect).y + EditorGUIUtility.singleLineHeight + 5,
            };
            var animFuncListRect = new Rect(hasFuncRect)
            {
                width = position.width,
                y = hasFuncRect.y + EditorGUIUtility.singleLineHeight + 5,
            };
            var isFuncDelayRect = new Rect(hasFunc.boolValue ? animFuncListRect : hasFuncRect)
            {
                y = (hasFunc.boolValue ? animFuncListRect : hasFuncRect).y + EditorGUI.GetPropertyHeight(animFuncList) + 5,
                width = hasFuncRect.width,
            };
            var funcDelayTimeRect = new Rect(hasFunc.boolValue ? animFuncListRect : hasFuncRect)
            {
                x = hasFuncRect.x + hasFuncRect.width,
                y = (hasFunc.boolValue ? animFuncListRect : hasFuncRect).y + EditorGUI.GetPropertyHeight(animFuncList) + 5,
                width = position.width - hasFuncRect.width,
            };
            var isSecondRect = new Rect(hasFunc.boolValue ? isFuncDelayRect : hasFuncRect)
            {
                width = position.width,
                y = (hasFunc.boolValue ? isFuncDelayRect : hasFuncRect).y + EditorGUIUtility.singleLineHeight + 5,
            };
            var interruptTimeRect = new Rect(isSecondRect)
            {
                y = isSecondRect.y + EditorGUIUtility.singleLineHeight + 5,
            };
            var isFrameRangeRect = new Rect(((AnimEventType)type.enumValueIndex == AnimEventType.StartAttack || (AnimEventType)type.enumValueIndex == AnimEventType.EndAttack ||
                    (AnimEventType)type.enumValueIndex == AnimEventType.StartSkill || (AnimEventType)type.enumValueIndex == AnimEventType.EndSkill) ? (hasFunc.boolValue ? isFuncDelayRect : hasFuncRect) : isSecondRect)
            {
                width = position.width / 2,
                y = (((AnimEventType)type.enumValueIndex == AnimEventType.StartAttack || (AnimEventType)type.enumValueIndex == AnimEventType.EndAttack ||
                    (AnimEventType)type.enumValueIndex == AnimEventType.StartSkill || (AnimEventType)type.enumValueIndex == AnimEventType.EndSkill) ? (hasFunc.boolValue ? isFuncDelayRect : hasFuncRect) : isSecondRect).y + EditorGUIUtility.singleLineHeight + 5,
            };
            var isAllFrameRangeRect = new Rect(((AnimEventType)type.enumValueIndex == AnimEventType.StartAttack || (AnimEventType)type.enumValueIndex == AnimEventType.EndAttack ||
                    (AnimEventType)type.enumValueIndex == AnimEventType.StartSkill || (AnimEventType)type.enumValueIndex == AnimEventType.EndSkill) ? (hasFunc.boolValue ? isFuncDelayRect : hasFuncRect) : isSecondRect)
            {
                x = position.x + position.width / 2,
                width = position.width / 2,
                y = (((AnimEventType)type.enumValueIndex == AnimEventType.StartAttack || (AnimEventType)type.enumValueIndex == AnimEventType.EndAttack ||
                    (AnimEventType)type.enumValueIndex == AnimEventType.StartSkill || (AnimEventType)type.enumValueIndex == AnimEventType.EndSkill) ? (hasFunc.boolValue ? isFuncDelayRect : hasFuncRect) : isSecondRect).y + EditorGUIUtility.singleLineHeight + 5,
            };
            var frameRangeRect = new Rect(isFrameRangeRect)
            {
                width = position.width,
                y = isAllFrameRangeRect.y + EditorGUIUtility.singleLineHeight + 5,
            };
            var frameNumberRect = new Rect(isFrameRangeRect)
            {
                width = position.width,
                y = isFrameRangeRect.y + EditorGUIUtility.singleLineHeight + 5,
            };
            foldout.boolValue = EditorGUI.Foldout(foldoutRect, foldout.boolValue, animEventName.stringValue, true);
            if (foldout.boolValue)
            {
                animEventName.stringValue = EditorGUI.TextField(animEventNameRect, animEventName.displayName, animEventName.stringValue);
                EditorGUI.PropertyField(typeRect, type);
                EditorGUI.PropertyField(hasFuncRect, hasFunc);
                if (hasFunc.boolValue)
                {
                    EditorGUI.PropertyField(animFuncListRect, animFuncList, new GUIContent("AnimFuncList"), true);
                    EditorGUI.PropertyField(isFuncDelayRect, isFuncDelay);
                    if (isFuncDelay.boolValue)
                    {
                        funcDelayTime.floatValue = EditorGUI.FloatField(funcDelayTimeRect, funcDelayTime.displayName, funcDelayTime.floatValue);
                    }
                }
                EditorGUI.PropertyField(hasSwitchAnimRect, hasSwitchAnim);
                if (hasSwitchAnim.boolValue)
                {
                    string[] animNames = controller.GetAnimNameList().ToArray();
                    switchAnimIndex.intValue = EditorGUI.Popup(switchAnimRect, switchAnimIndex.intValue, animNames);
                    switchAnim.stringValue = animNames[switchAnimIndex.intValue];
                    //EditorGUI.PropertyField(switchAnimRect, switchAnim);

                    EditorGUI.PropertyField(isSwitchDelayRect, isSwitchDelay);
                    if (isSwitchDelay.boolValue)
                    {
                        switchDelayTime.floatValue = EditorGUI.FloatField(switchDelayTimeRect, switchDelayTime.displayName, switchDelayTime.floatValue);
                    }
                }
                if ((AnimEventType)type.enumValueIndex == AnimEventType.StartAttack || (AnimEventType)type.enumValueIndex == AnimEventType.EndAttack ||
                    (AnimEventType)type.enumValueIndex == AnimEventType.StartSkill || (AnimEventType)type.enumValueIndex == AnimEventType.EndSkill)
                {
                    EditorGUI.PropertyField(isFrameRangeRect, isFrameRange);
                    if (isFrameRange.boolValue)
                    {
                        EditorGUI.PropertyField(isAllFrameRangeRect, isAllFrameRange);
                        if (!isAllFrameRange.boolValue)
                        {
                            EditorGUI.PropertyField(frameRangeRect, frameRange);
                        }
                    }
                    else
                    {
                        EditorGUI.PropertyField(frameNumberRect, frameNumber);
                    }
                }
                if ((AnimEventType)type.enumValueIndex == AnimEventType.Interrupt)
                {
                    EditorGUI.PropertyField(isSecondRect, isSecond);
                    if (isSecond.boolValue)
                    {
                        interruptTime.floatValue = EditorGUI.FloatField(interruptTimeRect, interruptTime.displayName, interruptTime.floatValue);
                    }
                    else
                    {
                        EditorGUI.PropertyField(isFrameRangeRect, isFrameRange);
                        if (isFrameRange.boolValue)
                        {
                            EditorGUI.PropertyField(isAllFrameRangeRect, isAllFrameRange);
                            if (!isAllFrameRange.boolValue)
                            {
                                EditorGUI.PropertyField(frameRangeRect, frameRange);
                            }
                        }
                        else
                        {
                            EditorGUI.PropertyField(frameNumberRect, frameNumber);
                        }
                    }
                }
            }
        }
    }
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        type = property.FindPropertyRelative("type");
        isFrameRange = property.FindPropertyRelative("isFrameRange");
        isAllFrameRange = property.FindPropertyRelative("isAllFrameRange");
        foldout = property.FindPropertyRelative("foldout");
        hasSwitchAnim = property.FindPropertyRelative("hasSwitchAnim");
        hasFunc = property.FindPropertyRelative("hasFunc");
        animFuncList = property.FindPropertyRelative("animFuncList");
        isSecond = property.FindPropertyRelative("isSecond");
        int totalHeight = 0;
        if (!foldout.boolValue) totalHeight += 1;
        else
        {
            totalHeight += 5;
            if (hasSwitchAnim.boolValue) { totalHeight++; }
            if (hasFunc.boolValue) { totalHeight += 1; }
            if ((AnimEventType)type.enumValueIndex == AnimEventType.StartAttack || (AnimEventType)type.enumValueIndex == AnimEventType.EndAttack ||
                (AnimEventType)type.enumValueIndex == AnimEventType.StartSkill || (AnimEventType)type.enumValueIndex == AnimEventType.EndSkill)
            {
                if (isFrameRange.boolValue && isAllFrameRange.boolValue) totalHeight += 1;
                else totalHeight += 2;
            }
            else if ((AnimEventType)type.enumValueIndex == AnimEventType.Interrupt)
            {
                if (isSecond.boolValue) { totalHeight += 2; }
                else if (isFrameRange.boolValue && isAllFrameRange.boolValue) totalHeight += 2;
                else totalHeight += 3;
            }
        }
        return base.GetPropertyHeight(property, label) * totalHeight + 5 * (totalHeight) + (hasFunc.boolValue && foldout.boolValue ? EditorGUI.GetPropertyHeight(animFuncList) : 0);
    }
}
